package com.tuanzi.loan.workflow.cmd;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricVariableInstance;
import org.activiti.engine.impl.HistoricVariableInstanceQueryImpl;
import org.activiti.engine.impl.interceptor.Command;
import org.activiti.engine.impl.interceptor.CommandContext;
import org.activiti.engine.impl.persistence.entity.*;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;

import com.tuanzi.loan.core.util.SpringContextHolder;
import com.tuanzi.loan.workflow.service.ScriptTaskService;

/**
 * 流程结束后强制来回命令
 * 
 * @author chenxf
 * @createDate 2016-4-15
 */
public class CallBackAfterEndingCmd implements Command<Object> {

	protected final Logger logger = LoggerFactory.getLogger(getClass());
	private String processInstanceId;
	private String taskId;
	private String activityId;
	private String delActivityId;
	private ScriptTaskService scriptTaskService;

	public CallBackAfterEndingCmd(String processInstanceId, String taskId, String activityId, String delActivityId) {
		super();
		this.processInstanceId = processInstanceId;
		this.taskId = taskId;
		this.activityId = activityId;
		this.delActivityId = delActivityId;
		this.scriptTaskService = SpringContextHolder.getBean(ScriptTaskService.class);
	}

	@Override
	public Object execute(CommandContext cmdCtx) {
		Date now = new Date();

		// 新增运行时任务记录
		HistoricTaskInstanceEntity hisTaskInstEntity = cmdCtx.getHistoricTaskInstanceEntityManager().findHistoricTaskInstanceById(taskId);
		TaskEntity taskEntity = new TaskEntity();
		BeanUtils.copyProperties(hisTaskInstEntity, taskEntity);
		taskEntity.setId(null);
		taskEntity.setCreateTime(now);
		cmdCtx.getTaskEntityManager().insert(taskEntity);

		// 新增历史活动记录
		Map<String, Object> parameterMap = new HashMap<String, Object>();
		parameterMap.put("sql", String.format("select * from ACT_HI_ACTINST where ACT_ID_ = '%s' and PROC_INST_ID_ = '%s' order by END_TIME_ desc", activityId, processInstanceId));
		List<HistoricActivityInstance> hisActInstList = cmdCtx.getHistoricActivityInstanceEntityManager().findHistoricActivityInstancesByNativeQuery(parameterMap, 1, 20);
		// 如果直接获取entity，则当该活动是被回退过，则会存在多条记录
		// HistoricActivityInstanceEntity hisActInstEntity =
		// cmdCtx.getHistoricActivityInstanceEntityManager().findHistoricActivityInstance(activityId,
		// processInstanceId);

		HistoricActivityInstanceEntity hisActInstEntity = (HistoricActivityInstanceEntity) hisActInstList.get(0);
		hisActInstEntity.setId(taskEntity.getId());
		hisActInstEntity.setTaskId(taskEntity.getId());
		hisActInstEntity.setStartTime(now);
		hisActInstEntity.setEndTime(null);
		hisActInstEntity.setDurationInMillis(null);
		cmdCtx.getHistoricActivityInstanceEntityManager().insert(hisActInstEntity);

		// 新增运行时实例
		HistoricProcessInstanceEntity hisProcInstEntity = cmdCtx.getHistoricProcessInstanceEntityManager().findHistoricProcessInstance(processInstanceId);
		ExecutionEntity executionEntity = new ExecutionEntity();
		BeanUtils.copyProperties(hisProcInstEntity, executionEntity);
		ExecutionEntity procInst = new ExecutionEntity();
		procInst.setId(hisProcInstEntity.getId());
		executionEntity.setProcessInstance(procInst);// 设置proc_inst_id

		ActivityImpl activity = new ActivityImpl(hisActInstEntity.getActivityId(), null);
		executionEntity.setActivity(activity);
		cmdCtx.getExecutionEntityManager().insert(executionEntity);

		// 新增运行时环境变量
		HistoricVariableInstanceQueryImpl hisVarInstQuery = new HistoricVariableInstanceQueryImpl().processInstanceId(processInstanceId);
		List<HistoricVariableInstance> hisVarInstEntityList = cmdCtx.getHistoricVariableInstanceEntityManager().findHistoricVariableInstancesByQueryCriteria(hisVarInstQuery, null);
		for (HistoricVariableInstance hisVarInstEntity : hisVarInstEntityList) {
			HistoricVariableInstanceEntity entity = (HistoricVariableInstanceEntity) hisVarInstEntity;
			VariableInstanceEntity varInstEntity = VariableInstanceEntity.create(entity.getName(), entity.getVariableType(), entity.getValue());
			varInstEntity.setId(entity.getId());
			varInstEntity.setExecutionId(processInstanceId);
			varInstEntity.setProcessInstanceId(processInstanceId);
			cmdCtx.getVariableInstanceEntityManager().insert(varInstEntity);
		}

		// 新增历史任务记录
		HistoricTaskInstanceEntity newHisTaskInstEntity = new HistoricTaskInstanceEntity();
		BeanUtils.copyProperties(hisTaskInstEntity, newHisTaskInstEntity);
		newHisTaskInstEntity.setId(taskEntity.getId());
		newHisTaskInstEntity.setStartTime(now);
		newHisTaskInstEntity.setClaimTime(now);
		newHisTaskInstEntity.setEndTime(null);
		newHisTaskInstEntity.setDurationInMillis(null);
		newHisTaskInstEntity.setDeleteReason(null);
		cmdCtx.getHistoricTaskInstanceEntityManager().insert(newHisTaskInstEntity);

		// 更新历史任务记录
		// HistoricActivityInstanceEntity delHisActInstEntity =
		// cmdCtx.getHistoricActivityInstanceEntityManager().findHistoricActivityInstance(delActivityId,
		// processInstanceId);
		// hisTaskInstEntity.setDeleteReason(delHisActInstEntity.getActivityId());
		hisTaskInstEntity.setDeleteReason(delActivityId);
		cmdCtx.getDbSqlSession().update(hisTaskInstEntity);

		// 删除结束活动记录
		// 实际上activiti并没有提供删除deleteHistoricActivityInstance
		HistoricActivityInstanceEntity delHisActInstEntity = cmdCtx.getHistoricActivityInstanceEntityManager().findHistoricActivityInstance(delActivityId, processInstanceId);

//		WebApplicationContext applicationContext = ContextLoader.getCurrentWebApplicationContext();
//		if (Objects.isNull(activitiCommonService)) {
//			activitiCommonService = applicationContext.getBean("activitiCommonService", ActivitiCommonServiceImpl.class);
//		}
//		activitiCommonService.deleteActHiInstBy(delHisActInstEntity.getId());
//
//		// 更新历史流程实例记录
//		hisProcInstEntity.setEndActivityId(null);
//		hisProcInstEntity.setEndTime(null);
//		hisProcInstEntity.setDurationInMillis(null);
//		cmdCtx.getDbSqlSession().update(hisProcInstEntity);
//
//		// 执行重做脚本
//		ScriptTaskQueryRequest request = new ScriptTaskQueryRequest();
//		request.setProcDefId(hisProcInstEntity.getProcessDefinitionId());
//		request.setTaskType(ScriptTask.TASK_TYPE_CALLBACK);
//		request.setActivityId("endevent");
//		BaseResponse<ScriptTaskResponse> response = workflowScriptService.getScriptTaskVO(request);
//		ScriptTaskResponse scriptVO = response.getResult().getData();
//		if (scriptVO != null) {
//			Map<String, Object> param = new HashMap<String, Object>();
//			param.put("processor", applicationContext.getBean("workflowProcessorService", WorkflowProcessorServiceImpl.class)); // 预置流程处理服务对象
//			param.put("procInst", hisProcInstEntity); // 预置流程实例对象
//			try {
//				ScriptTaskRunRequest runRequest = new ScriptTaskRunRequest();
//				runRequest.setScriptTaskResponse(scriptVO);
//				runRequest.setParam(param);
//				workflowScriptService.runScript(runRequest);
//			} catch (Exception e) {
//				throw new RuntimeException(e);
//			}
//		}

		return executionEntity;
	}

}
